﻿using System;
using System.Linq;
using System.Collections.Generic;
using SIM.Geo.DA;
using SIM.Geo.BE;
using System.Transactions;

namespace SIM.Geo.BL
{
    public class BLSondaje
    {
        #region Metodos

        /// <summary>
        /// Metódo que devuelve lista de sondaje
        /// </summary>
        /// <returns></returns>
        public List<Sondaje> ListarSondaje()
        {
            return Accesor.ListarSondaje();
        }

        /// <summary>
        /// Metodo que inserta un nuevo sondaje
        /// </summary>
        /// <param name="labor"></param>
        /// <returns></returns>
        public int InsertarSondaje(Sondaje sondaje)
        {
            sondaje.CodigoSondaje = Accesor.GenerarCodigoSondaje();
            return Accesor.InsertarSondaje(sondaje);
        }

        /// <summary>
        /// Metodo que modifica sondaje
        /// </summary>
        /// <param name="labor"></param>
        public void ModificarSondaje(Sondaje sondaje)
        {

            var sondajeEdit = Accesor.ObtenerSondaje(sondaje.CodigoSondaje);
            sondajeEdit.CodigoZona = sondaje.CodigoZona;
            sondajeEdit.CodigoGeologo = sondaje.CodigoGeologo;
            sondajeEdit.CodigoLabor = sondaje.CodigoLabor;
            sondajeEdit.CodigoEmpresa = sondaje.CodigoEmpresa;
            sondajeEdit.CodigoMaquina = sondaje.CodigoMaquina;
            sondajeEdit.FechaInicio = sondaje.FechaInicio;
            sondajeEdit.FechaFin = sondaje.FechaFin;
            sondajeEdit.Seccion = sondaje.Seccion;
            sondajeEdit.Distancia = sondaje.Distancia;
            sondajeEdit.CumpleLitologia = sondaje.CumpleLitologia;
            sondajeEdit.CumpleMuestra = sondaje.CumpleMuestra;
            sondajeEdit.CumpleGeomecanica = sondaje.CumpleGeomecanica;
            sondajeEdit.CumpleEstructura = sondaje.CumpleEstructura;
            sondajeEdit.Observacion = sondaje.Observacion;
            Accesor.ModificarSondaje(sondajeEdit);
        }
        /// <summary>
        /// Metodo que modifica sondaje
        /// </summary>
        /// <param name="labor"></param>
        public void ModificarSondajeTaladro(Sondaje sondaje)
        {

            var sondajeEdit = Accesor.ObtenerSondaje(sondaje.CodigoSondaje);
            sondajeEdit.CodigoZona = sondaje.CodigoZona;
            sondajeEdit.CodigoGeologo = sondaje.CodigoGeologo;
            sondajeEdit.CodigoLabor = sondaje.CodigoLabor;
            sondajeEdit.CodigoEmpresa = sondaje.CodigoEmpresa;
            sondajeEdit.CodigoMaquina = sondaje.CodigoMaquina;
            sondajeEdit.FechaInicio = sondaje.FechaInicio;
            sondajeEdit.FechaFin = sondaje.FechaFin;
            sondajeEdit.Seccion = sondaje.Seccion;
            sondajeEdit.Distancia = sondaje.Distancia;
            //sondajeEdit.CumpleLitologia = sondaje.CumpleLitologia;
            sondajeEdit.CumpleMuestra = sondaje.CumpleMuestra;
            //sondajeEdit.CumpleGeomecanica = sondaje.CumpleGeomecanica;
            //sondajeEdit.CumpleEstructura = sondaje.CumpleEstructura;
            sondajeEdit.Observacion = sondaje.Observacion;
            sondajeEdit.AuxiliarSeccion = sondaje.AuxiliarSeccion;
            sondajeEdit.Fila = sondajeEdit.Fila;
            Accesor.ModificarSondaje(sondajeEdit);
        }
        /// <summary>
        /// Metodo que elimina sondaje
        /// </summary>
        /// <param name="labor"></param>
        public void EliminarSondaje(int codigoSondaje)
        {
            var sondaje = Accesor.ObtenerSondaje(codigoSondaje);
            Accesor.EliminarSondaje(sondaje);
        }

        /// <summary>
        /// Metodo que buscar por nombre de sondaje, anio, codigo de zona, estado y codigo de categoria de sondaje
        /// </summary>
        /// <param name="nombre"></param>
        /// <returns></returns>
        public List<BuscarSondajes_Result> BuscarSondaje(string nombreDDH, string anio, int codigoZona, int estado, int codigoCategoriaSondaje, int codigoClaseSondaje)
        {

            return Accesor.BuscarSondaje(nombreDDH, anio, codigoZona, estado, codigoCategoriaSondaje, codigoClaseSondaje);

        }

        /// <summary>
        /// Metodo que devuelve un sondaje por código
        /// </summary>
        /// <param name="codigoLabor"></param>
        /// <returns></returns>
        public Sondaje ObtenerSondaje(int codigoSondaje)
        {

            var sondaje = Accesor.ObtenerSondaje(codigoSondaje);
            if (sondaje != null)
            {
                sondaje.Zona = new DAZona().ObtenerZona(sondaje.CodigoZona);
                if (sondaje.CodigoLabor != null)
                {
                    sondaje.Labor = new DALabor().Obtener((int)sondaje.CodigoLabor);
                }
            }
            return sondaje;
        }

        /// <summary>
        /// Metodo que devuelve un Labor por código
        /// </summary>
        /// <param name="codigoLabor"></param>
        /// <returns></returns>
        public int ObtenerMaximoCodigo()
        {
            int codigoMaximo = 1;
            var lista = Accesor.ListarSondaje();
            if (lista.Count > 0)
            {
                codigoMaximo = lista.OrderByDescending(x => x.CodigoSondaje).FirstOrDefault().CodigoSondaje + 1;
            }

            return codigoMaximo;
        }

        /// <summary>
        /// Lista sondajes por Nombre de  DDH, si usa para hacer validaciones en la App
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <returns></returns>
        public List<Sondaje> ListarSondajePorNombreDDH(string nombreDDH)
        {
            return Accesor.ListarSondajePorNombreDDH(nombreDDH);
        }

        /// <summary>
        /// Metodo que permite Cambiar estado de sondajes
        /// </summary>
        /// <param name="codigosSondaje">recibe lista de sondajes a actualizar el estado</param>
        /// <param name="estado">Estado a actualizar en sondajes</param>
        public void CambiarEstadoSondajes(List<int> codigosSondaje, short estado)
        {
            foreach (int codigoSondaje in codigosSondaje)
            {
                var sondaje = Accesor.ObtenerSondaje(codigoSondaje);
                if (sondaje != null)
                {
                    //Modifica el estado de sondaje si solo si el estado nuevo es distinto al estado actual
                    if (sondaje.Estado != estado)
                    {
                        sondaje.Estado = estado;
                        Accesor.ModificarSondaje(sondaje);
                    }
                }
            }
        }

        /// <summary>
        /// Valida y finaliza sondajes
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <returns></returns>
        public string FinalizarSondaje(List<int> codigoSondajes)
        {
            string result = string.Empty;
            using (TransactionScope transaction = new TransactionScope())
            {
                foreach (var codigoSondaje in codigoSondajes)
                {
                    result = Accesor.FinalizarSondaje(codigoSondaje);
                    if (result.CompareTo("Finalizado") != 0)
                    {
                        break;
                    }
                }

                if (result.CompareTo("Finalizado") == 0)
                {
                    transaction.Complete();
                }
            }

            return result;
        }

        /// <summary>
        /// Valida y finaliza sondajes
        /// </summary>
        /// <param name="codigoSondaje"></param>
        /// <returns></returns>
        public string FinalizarSondajeTaladroLargo(List<int> codigoSondajes)
        {
            string result = string.Empty;
            using (TransactionScope transaction = new TransactionScope())
            {
                foreach (var codigoSondaje in codigoSondajes)
                {
                    result = Accesor.FinalizarSondajeTaladroLargo(codigoSondaje);
                    if (result.CompareTo("Finalizado") != 0)
                    {
                        break;
                    }
                }

                if (result.CompareTo("Finalizado") == 0)
                {
                    transaction.Complete();
                }
            }

            return result;
        }

        /// <summary>
        /// Valida y actualiza cumplimiento
        /// </summary>
        /// <param name="codigoSondaje">codigo de sondaje</param>
        /// <param name="tipoAnalisis">1=Litologia, 2=Muestra, 3=Geomecanica, 4=Estructura</param>
        /// <returns></returns>
        public string FinalizarCumplimiento(int codigoSondaje, int tipoAnalisis)
        {
            string result = string.Empty;
            using (TransactionScope transaction = new TransactionScope())
            {
                result = Accesor.FinalizarCumplimiento(codigoSondaje, tipoAnalisis);
                if (result.CompareTo("Cumplido") == 0)
                {
                    transaction.Complete();
                }
            }

            return result;
        }

        /// <summary>
        /// Busca sondaje por ubicacion de sondaje
        /// </summary>
        /// <param name="anio"></param>
        /// <param name="codigoZona"></param>
        /// <param name="estado"></param>
        /// <param name="codigoCategoriaSondaje"></param>
        /// <returns></returns>
        public List<buscarSondajesUbicacion_Result> BuscarSondajePorUbicacion(string anio, int codigoZona, int estado, int codigoCategoriaSondaje, int ubicacion)
        {
            return Accesor.BuscarSondajePorUbicacion(anio, codigoZona, estado, codigoCategoriaSondaje, ubicacion);
        }

        /// <summary>
        /// Metodo que actualiza ubicacion sondaje
        /// </summary>
        /// <param name="labor"></param>
        public void ActualizarUbicacionSondaje(Sondaje sondaje)
        {

            var sondajeEdit = Accesor.ObtenerSondaje(sondaje.CodigoSondaje);
            sondajeEdit.Este = sondaje.Este;
            sondajeEdit.Norte = sondaje.Norte;
            sondajeEdit.Cota = sondaje.Cota;
            sondajeEdit.Inclinacion = sondaje.Inclinacion;
            sondajeEdit.Azimut = sondaje.Azimut;
            Accesor.ModificarSondaje(sondajeEdit);
        }

        /// <summary>
        /// Consulta de sondajes
        /// </summary>
        /// <param name="nombreDDH"></param>
        /// <param name="anio"></param>
        /// <param name="codigoZona"></param>
        /// <param name="estado"></param>
        /// <param name="codigoCategoriaSondaje"></param>
        /// <returns></returns>
        public List<consultarSondajes_Result> ConsultarSondajes(string nombreDDH, string anio, int codigoZona, int estado, int codigoCategoriaSondaje, int codigoClaseSondaje)
        {
            return Accesor.ConsultarSondajes(nombreDDH, anio, codigoZona, estado, codigoCategoriaSondaje, codigoClaseSondaje);
        }

        /// <summary>
        /// Metodo que realiza importacion de Sondaje [Taladro Largo] y sus muestras
        /// </summary>
        /// <param name="sondajes"></param>
        /// <returns></returns>
        public string ImportarSondajeYMuestra1(List<Sondaje> sondajes)
        {
            string retorno = "NoImportado";
            DACodigoMuestra daCodigoMuestra = new DACodigoMuestra();

            using (TransactionScope transaction = new TransactionScope())
            {
                foreach (var item in sondajes)
                {
                    item.CodigoSondaje = Accesor.GenerarCodigoSondaje();
                    Accesor.InsertarSondaje(item);

                    foreach (var codigoMuestraSondaje in item.MuestraSondaje)
                    {
                        var codigoMuestra = daCodigoMuestra.ObtenerCodigoMuestra(codigoMuestraSondaje.CodigoMuestraSondaje);
                        if (codigoMuestra != null)
                        {
                            codigoMuestra.CodigoEstado = 2; //ASOCIADO
                            daCodigoMuestra.ModificarCodigoMuestra(codigoMuestra);
                        }
                    }
                }


                transaction.Complete();
                retorno = "Importado";
            }

            return retorno;
        }

        /// <summary>
        /// Metodo que realiza importacion de Sondaje [Taladro Largo] y sus muestras
        /// </summary>
        /// <param name="sondajes"></param>
        /// <returns></returns>
        public string ImportarSondajeYMuestra(List<SondajeImportacion> sondajes)
        {
            string retorno = "NoImportado";
            var validacion = sondajes.Where(x => x.Validacion.CompareTo("Correcto") != 0).ToList();
            if (validacion.Count > 0)
            {
                retorno = "Existen incostencias";
            }

            List<string> taladros = sondajes.Select(x => x.TLG).Distinct().ToList();
            List<Sondaje> listaSondajesGrabar = new List<Sondaje>();
            Sondaje sondajeGrabar = null;
            foreach (var codigoTaladro in taladros)
            {
                var taladro = sondajes.Where(x => x.TLG.CompareTo(codigoTaladro) == 0).FirstOrDefault();
                if (taladro != null)
                {
                    sondajeGrabar = new Sondaje();

                    sondajeGrabar.CodigoSondaje = 0;
                    sondajeGrabar.NombreDDH = taladro.TLG;
                    sondajeGrabar.NumeroSondaje = taladro.NumeroSondaje;
                    sondajeGrabar.FechaInicio = taladro.Fecha;
                    sondajeGrabar.FechaFin = null;
                    sondajeGrabar.Seccion = (int)taladro.Seccion;
                    sondajeGrabar.CumpleLitologia = 0;
                    sondajeGrabar.CumpleMuestra = 0;
                    sondajeGrabar.CumpleGeomecanica = 0;
                    sondajeGrabar.CumpleEstructura = 0;
                    sondajeGrabar.Observacion = taladro.Observacion;
                    sondajeGrabar.Norte = taladro.Norte;
                    sondajeGrabar.Este = taladro.Este;
                    sondajeGrabar.Cota = taladro.Cota;
                    sondajeGrabar.Distancia = taladro.Distancia;
                    sondajeGrabar.Azimut = taladro.Azimut;
                    sondajeGrabar.Inclinacion = taladro.Azimut;
                    sondajeGrabar.Estado = taladro.Estado; //Iniciado
                    sondajeGrabar.CodigoMaquina = taladro.CodigoMaquina;  //Maquina
                    sondajeGrabar.CodigoLabor = taladro.CodigoLabor; //Codigo de Labor

                    sondajeGrabar.CodigoGeologo = taladro.CodigoGeologo; //Codigo de Geologo
                    sondajeGrabar.Anio = taladro.Anio; // Año
                    sondajeGrabar.Fila = taladro.Fila;
                    sondajeGrabar.CodigoZona = taladro.CodigoZona; // Codigo de Zona
                    sondajeGrabar.CodigoCategoriaSondaje = taladro.CodigoCategoriaSondaje; // CategoriaSondaje
                    sondajeGrabar.NumeroSondaje = taladro.NumeroSondaje;
                    sondajeGrabar.CodigoClaseSondaje = taladro.CodigoClaseSondaje; // Clase Sondaje
                    sondajeGrabar.CodigoEmpresa = taladro.CodigoEmpresa; // Codigo de Empresa
                    sondajeGrabar.CumplioLitologia = 0;
                    sondajeGrabar.CumplioMuestra = 0;
                    sondajeGrabar.CumplioGeomecanica = 0;
                    sondajeGrabar.CumplioEstructura = 0;

                    var muestras = sondajes.Where(x => x.TLG.CompareTo(codigoTaladro) == 0).ToList();
                    MuestraSondaje muestra = null;
                    List<MuestraSondaje> listaMuestra = null;
                    foreach (var imuestra in muestras)
                    {
                        if (listaMuestra == null) listaMuestra = new List<MuestraSondaje>();

                        muestra = new MuestraSondaje();

                        muestra.CodigoMuestraSondaje = imuestra.CodigoMuestra;
                        muestra.Desde = (double)imuestra.Desde;
                        muestra.Hasta = (double)imuestra.Hasta;
                        muestra.ValorAg = -1;
                        muestra.ValorPb = -1;
                        muestra.ValorZn = -1;
                        muestra.ValorCu = -1;
                        muestra.ValorFe = -1;
                        muestra.Observacion = imuestra.Observacion;
                        muestra.Estado = 1; //Registrado
                        muestra.CodigoMuestraSondajeDuplicado = null;
                        muestra.CodigoTipoControlCalidad = 1;
                        muestra.CodigoTomadorMuestra = 5; //Falta completar
                        muestra.FechaEnvio = imuestra.Fecha;
                        muestra.CodigoGeologo = imuestra.CodigoGeologo;

                        listaMuestra.Add(muestra);
                    }
                    sondajeGrabar.MuestraSondaje = listaMuestra; //Asigno las muestras
                    listaSondajesGrabar.Add(sondajeGrabar);
                }
            }

            //Inserta Sondajes
            using (TransactionScope transaction = new TransactionScope())
            {
                foreach (var item in listaSondajesGrabar)
                {

                    item.CodigoSondaje = Accesor.GenerarCodigoSondaje();
                    Accesor.InsertarSondaje(item);

                }

                transaction.Complete();
                retorno = "Importado";
            }

            return retorno;
        }

        /// <summary>
        /// Método la importación de taladros
        /// </summary>
        /// <param name="leymuestra"></param>
        public List<SondajeImportacion> ValidarTaladrosImportacion(List<SondajeImportacion> taladros)
        {
            bool valida = true;

            //Valida que no exista los taladros registrados
            List<string> nombreTaladros = taladros.Select(x => x.TLG).Distinct().ToList();
            List<string> codigoMuestas = taladros.Select(x => x.CodigoMuestra).Distinct().ToList();

            DAMuestraSondaje daMuestraSondaje = new DAMuestraSondaje();
            DACodigoMuestra daCodigoMuestra = new DACodigoMuestra();

            var muestras = daMuestraSondaje.ListarMuestraSondajePorcodigos(codigoMuestas);
            var sondajes = Accesor.ListarMuestraSondajePorNombres(nombreTaladros);
            var codigosGenerados = daCodigoMuestra.ListarCodigoMuestraPorCodigos(codigoMuestas, 4); //Muestras Generados para Taladros

            List<SondajeImportacion> validados = new List<SondajeImportacion>();
            foreach (var item in taladros)
            {
                valida = true;
                item.Validacion = string.Empty;

                if (item.TLG.Length != 10)
                {
                    item.Validacion = "Nombre de Taladro no es válido. ";
                    valida = false;
                }

                var codigoGenerado = codigosGenerados.Where(x => x.CodigoMuestra1 == item.CodigoMuestra).FirstOrDefault();
                if (codigoGenerado == null)
                {
                    item.Validacion = item.Validacion + " Código de muestra no generado. ";
                    valida = false;
                }

                var taladro = sondajes.Where(x => x.NombreDDH.ToUpper() == item.TLG.ToUpper()).FirstOrDefault();
                if (taladro != null)
                {
                    item.Validacion = item.Validacion + "Nombre de taladro ya existe. ";
                    valida = false;
                }

                var muestra = muestras.Where(x => x.CodigoMuestraSondaje == item.CodigoMuestra).FirstOrDefault();
                if (muestra != null)
                {
                    item.Validacion = item.Validacion + "Muestra ya se encuentra registrado. ";
                    valida = false;
                }

                if (item.Fecha.Year < 1990)
                {
                    item.Validacion = item.Validacion + "Fecha no es válido.";
                    valida = false;
                }

                if (valida)
                {
                    item.Validacion = "Correcto";
                }
                validados.Add(item);
            }


            return validados;
        }
        #endregion

        #region Accesor
        private static DASondaje Accesor
        {
            [System.Diagnostics.DebuggerStepThrough]
            get { return new DASondaje(); }
        }
        #endregion
    }
}
